﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.Utils;
using DevExpress.XtraGrid.Columns;
using System.Threading;

namespace DevGrid
{
    public delegate void DataRowClickEventHandler(DataRow dataRow, MouseEventArgs e);
    public partial class DevGridView : UserControl
    {
        int lastselect = 0;
        DataTable dt;
        private int m_maxrowcount = 100;
        object[] lastselectobj;
        object mhandle = 0;
        public event DataRowClickEventHandler RowClick;
        private bool isparamunit = false;
        private bool isbestfit = false;

        public Dictionary<string, string> ParamUnit = new Dictionary<string, string>();
        public DevGridView()
        {
            InitializeComponent();
            if (!IsDesignMode)
            {
                gridView1.RowCellStyle += gridView1_RowCellStyle;
                //gridView1.TopRowChanged += GridView1_TopRowChanged;
               // gridView1.RowStyle += GridView1_RowStyle1;
                gridView1.RowClick += GridView1_RowClick;
                gridView1.RowStyle += GridView1_RowStyle;

            }
        }


        private void GridView1_RowStyle1(object sender, RowStyleEventArgs e)
        {
          
            //if(e.)
            //if (e.CellValue == null) return;
            //if (e.CellValue.ToString().Contains("NG"))
            //    e.Appearance.BackColor = Color.Red;
        }

        private void GridView1_RowStyle(object sender, RowStyleEventArgs e)
        {
          
            int handle = e.RowHandle;
            if (handle >= 0)
            {
                object[] m_selectobj = gridView1.GetDataRow(handle).ItemArray;
                if (m_selectobj != null&& lastselectobj!=null)
                {
                    for (int i = 0; i < m_selectobj.Length; i++)
                    {
                        if (!m_selectobj[i].Equals(lastselectobj[i]))
                        {
                            return;
                        }
                    }
                    gridView1.FocusedRowHandle = handle;
                }
            }
           
        }

        private void GridView1_RowClick(object sender, RowClickEventArgs e)
        {
            int handle = e.RowHandle;
            gridView1.FocusedRowHandle = handle;
            lastselectobj = gridView1.GetDataRow(e.RowHandle).ItemArray;
            RowClick?.Invoke(gridView1.GetDataRow(e.RowHandle), e);
        }

        public int C_MaxRowCount
        {
            get
            {
                return m_maxrowcount;
            }
            set
            {
                m_maxrowcount = value;
            }
        }

        public void BestFitColumns()
        {
            gridView1.BestFitColumns();
        }


        public void RefreshDataSource()
        {
            gridControl1.RefreshDataSource();
        }

        
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public DataTable DataTable
        {
            set
            {

                if (IsDesignMode) return;

                if (value == null) return;

                if (!CompareDataTable(dt, value))
                {
                    dt = value.Clone();
                    gridView1.Columns.Clear();
                    gridControl1.DataSource = dt;
                    gridControl1.RefreshDataSource();
                }
                IEqualityComparer<DataRow> comparer = DataRowComparer.Default;
                int maxcount = Math.Max(value.Rows.Count, dt.Rows.Count);
                int linenumtochange = value.Rows.Count - dt.Rows.Count;
                int num = value.Rows.Count;
                if (value.Rows.Count != dt.Rows.Count)
                {
                    for (int k = 0; k < Math.Abs(linenumtochange); k++)
                    {
                        if (linenumtochange > 0)
                            dt.Rows.Add(dt.NewRow());
                        if (linenumtochange < 0)
                            dt.Rows.Remove(dt.Rows[dt.Rows.Count - 1]);
                    }
                }
                for (int k = 0; k < num; k++)
                {
                    if (!comparer.Equals(value.Rows[k], dt.Rows[k]))
                    {
                        dt.Rows[k].ItemArray = value.Rows[k].ItemArray;

                    }
                }
                if (gridView1.Columns.Count > 0)
                {
                    if (!isparamunit && ParamUnit.Count > 0)
                    {
                        for (int i = 0; i < gridView1.Columns.Count; i++)
                        {
                            if (ParamUnit.ContainsKey(gridView1.Columns[i].FieldName))
                            {
                                gridView1.Columns[i].Caption = gridView1.Columns[i].FieldName + "(" + ParamUnit[gridView1.Columns[i].FieldName] + ")";
                                isparamunit = true;
                                isbestfit = true;
                            }
                        }
                    }
                    if (gridView1.Columns[0].Width == gridView1.Columns[1].Width && dt.Rows.Count > 0|| isbestfit)
                    {
                        isbestfit = false;
                        for (int k = 0; k < dt.Columns.Count; k++)
                        {
                            if (dt.Columns[k].DataType == typeof(DateTime))
                            {
                                gridView1.Columns[k].DisplayFormat.FormatString = "yyyy-MM-dd HH:mm:ss";
                                gridView1.Columns[k].DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
                            }
                        }
                        gridView1.BestFitColumns();
                        for (int k = 0; k < dt.Columns.Count; k++)
                        {
                            if (dt.Columns[k].DataType == typeof(DateTime))
                            {
                                gridView1.Columns[k].DisplayFormat.FormatString = "yyyy-MM-dd HH:mm:ss";
                                gridView1.Columns[k].DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
                            }
                        }
                        gridView1.BestFitColumns();
                    }
                }
    
            }
            get
            {
                return dt;
            }
        }

        public void SetTimeFormat(string columnName, string stringFormat)
        {
            DevExpress.XtraGrid.Columns.GridColumn gridColumn = gridView1.Columns.Where(t => t.Name.Contains(columnName)).FirstOrDefault();
            if (gridColumn != null)
            {
                gridColumn.DisplayFormat.FormatString = stringFormat;
                gridColumn.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
            }
        }

        public  bool IsDesignMode
        {
            get
            {
                bool returnFlag = false;
                if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
                {
                    returnFlag = true;
                }
                else if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv")
                {
                    returnFlag = true;
                }
                return returnFlag;
            }
        }

        private bool CompareDataTable(DataTable dt1, DataTable dt2, bool order = true)
        {
            if (dt1 != null && dt2 != null && dt1.Columns.Count == dt2.Columns.Count)
            {
                if (order)
                {
                    for (int i = 0; i < dt1.Columns.Count; i++)
                    {
                        if (dt1.Columns[i].DataType != dt2.Columns[i].DataType)
                        {
                            return false;
                        }
                    }
                }
                else
                {
                    foreach (DataColumn column in dt1.Columns)
                    {
                        if (dt2.Columns.Contains(column.ColumnName))
                        {
                            if (dt2.Columns[column.ColumnName].DataType != column.DataType)
                            {
                                return false;
                            }
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
            }
            else
            {
                return false;
            }
            return true;
        }

        private void SetFocus(int rowHandle)
        {
            for (int i = 0; i < this.gridView1.RowCount; i++)
            {
                gridView1.UnselectRow(i);
            }
            //当rowHandle是-1时选中最后一条（新增时使用）
            if (rowHandle == -1)
            {
                rowHandle = this.gridView1.RowCount;
            }
            if ((rowHandle != -1) && (this.gridView1.RowCount <= rowHandle))
            {
                rowHandle = this.gridView1.RowCount - 1;
            }
            this.gridView1.SelectRow(rowHandle);
            this.gridView1.FocusedRowHandle = rowHandle;
        }

        private void gridView1_RowCellStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs e)
        {
            try
            {
                if (e.CellValue == null) return;
                object[] dataRow = gridView1.GetDataRow(e.RowHandle).ItemArray;
                if (dataRow.Contains("NG"))
                {
                    e.Appearance.BackColor = Color.Orange;
                }
                if (e.CellValue.ToString()=="NG")
                {
                    e.Appearance.BackColor = Color.Red;
                }
            }
            catch { }
        }

        public void C_CollumnsAdd(string name, Type type, int length)
        {
            dt.Columns.Add(name, type);
            DevExpress.XtraGrid.Columns.GridColumn gridC = new DevExpress.XtraGrid.Columns.GridColumn();
            gridC.Width = length;
            gridC.Caption = name;
            gridC.FieldName = name;
            gridC.Visible = true;
            gridView1.Columns.Add(gridC);
        }

        public void C_AddNewRow(object[] objArry)
        {
            if (dt.Rows.Count == 0)
            {
                gridControl1.DataSource = dt;
            }
            this.Invoke(new Action(() =>
            {

                if (dt.Columns.Count != objArry.Length)
                {
                    throw new Exception("输入的值与表格结构不一致！");
                }
                DataRow dataRow = dt.NewRow();
                dataRow.ItemArray = objArry;
                dt.Rows.InsertAt(dataRow, 0);
                SetFocus(lastselect);
                int m = gridView1.RowCount;
                if (m > m_maxrowcount)
                {
                    dt.Rows[m - 1].Delete();
                }
                //gridView1.BestFitColumns();
            }));
        }
    }
}
